{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "874aa14a-a535-495a-aa08-ed3d62a23a43",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "# 👋🌍 Hello, world: Submit a Cirq job to Quantinuum\n",
    "\n",
    "In this notebook, we'll review the basics of Azure Quantum by submitting a simple *job*, or quantum program, to [Quantinuum](https://www.quantinuum.com/). We will use [Cirq](https://quantumai.google/cirq) to express the quantum job."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fcc9571d-b512-41c6-98e7-607cf1925490",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "## Submit a simple job to Quantinuum using Azure Quantum\n",
    "Azure Quantum provides several ways to express quantum programs. In this example, we are using Cirq, but note that Q# and Qiskit are also supported. All code in this example will be written in Python.\n",
    "\n",
    "Let's begin. When you see a code block, hover over it and click the triangle play-button to execute it. To avoid any compilation issues, this should be done in order from top to bottom."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f2aeaa5e-2234-42d9-bb8a-c2d9b6006b5a",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 1. Connect to the Azure Quantum workspace\n",
    "\n",
    "To connect to the Azure Quantum service, construct an instance of the `AzureQuantumService`. Note that it's imported from `azure.quantum.cirq`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "62d7cd5e-f3e9-4659-a0fb-b179fb8d74ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "from azure.quantum.cirq import AzureQuantumService\n",
    "service = AzureQuantumService (\n",
    "    resource_id = \"\",\n",
    "    location = \"\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "544be903-2e4c-4128-bc7c-149db1a40878",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "Let's see what providers and targets are enabled in this workspace with the following command:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d3ba8c8e-5061-4c74-bd85-734e8dda3300",
   "metadata": {
    "jupyter": {
     "outputs_hidden": false,
     "source_hidden": false
    },
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "outputs": [],
   "source": [
    "print(\"This workspace's targets:\")\n",
    "for target in service.targets():\n",
    "    print(\"-\", target.name)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a180e9d-eb5c-4cf9-aebd-71babfde5dcd",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### ❕ Do you see `quantinuum.sim.h1-1sc` in your list of targets? If so, you're ready to keep going.\n",
    "\n",
    "Don't see it? You may need to add Quantinuum to your workspace to run this sample. Navigate to the **Providers** page in the portal and click **+Add** to add the Quantinuum provider. Don't worry, there's a free credits plan available.\n",
    "\n",
    "## Quantinuum: The quantum provider\n",
    "Azure Quantum partners with third-party companies to deliver solutions to quantum jobs. These company offerings are called *providers*. Each provider can offer multiple *targets* with different capabilities. See the table below for Quantinuum's H1-1 device targets.\n",
    "\n",
    "| Target name | Target ID | Number of qubits | Description|\n",
    "| --- | ---| ---|---|\n",
    "H1-1 Syntax Checker | `quantinuum.sim.h1-1sc` | 20 | Quantinuum's H1-1 Syntax Checker. This will return all zeros in place of actual or simulated results. Use this to validate quantum programs against the H1-1 compiler before submitting to hardware or emulators on Quantinuum's platform. Free of cost. |\n",
    "H2-1 Syntax Checker | `quantinuum.sim.h2-1sc` | 32 | Quantinuum's H2-1 Syntax Checker. This will return all zeros in place of actual or simulated results. Use this to validate quantum programs against the H2-1 compiler before submitting to hardware or emulators on Quantinuum's platform. Free of cost.  |\n",
    "H1-1 Emulator | `quantinuum.sim.h1-1e` | 20 | Quantinuum's H1-1 Emulator. Uses a realistic physical model and noise model of H1-1. |\n",
    "H2-1 Emulator | `quantinuum.sim.h2-1e` | 32 | Quantinuum's H2-1 Emulator. Uses a realistic physical model and noise model of H2-1. |\n",
    "H1-1 | `quantinuum.qpu.h1-1` | 20 | Quantinuum's H1-1 trapped ion device. |\n",
    "H2-1 | `quantinuum.qpu.h2-1` | 32 | Quantinuum's H2-1 trapped ion device. |\n",
    "\n",
    "For this example, we will use `quantinuum.sim.h1-1sc` to avoid any costs or credit usage. If you wish to emulate or run the actual circuit, you may replace all instances of `quantinuum.sim.h1-1sc` in subsequent code cells with one of the other values in the table above, but please note any costs incurred. To learn more about Quantinuum's targets, check out our [documentation](https://aka.ms/AQ/Quantinuum/Documentation)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09e7472f-4736-493c-9b7c-a3761a563699",
   "metadata": {},
   "source": [
    "### 2. Build the quantum program\n",
    "\n",
    "Let's create a simple Cirq circuit to run."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "317c93e8-70ee-4a27-8d43-6645becb4805",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cirq\n",
    "\n",
    "q0 = cirq.LineQubit(0)\n",
    "circuit = cirq.Circuit(\n",
    "    cirq.H(q0),                # Apply an H-gate to q0\n",
    "    cirq.measure(q0, key=\"0\")  # Measure q0\n",
    ")\n",
    "circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdab1ecc-75e9-4a58-be51-82b2d6a87fe4",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The circuit you built is a simple quantum random bit generator. With Quantinuum's Syntax Checker, we will be able to confirm that the circuit is able to be run on their H1 emulator and hardware."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f93f68d-2266-4eed-bd94-955552fd42d1",
   "metadata": {},
   "source": [
    "### 3. Submit the quantum program to Quantinuum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abc18e20-3aad-44d7-a3a1-cd3f0f28bfd9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Using the Quantinuum Syntax Checker target, call \"run\" to submit the job. We'll\n",
    "# use 100 repetitions (simulated runs).\n",
    "job = service.targets(\"quantinuum.sim.h1-1sc\").submit(circuit, name=\"hello world-cirq-quantinuum\", repetitions=100)\n",
    "\n",
    "# Print the job ID.\n",
    "print(\"Job id:\", job.job_id())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8c4e40c-73be-47f8-bdfa-bd8aea5fa27b",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "The job ID can be used to retrieve the results later using the `get_job` function or by viewing it under the **Job management** section of the portal."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c16212d6-8c4a-4565-aa50-2ec883564e03",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 4. Obtain the job results\n",
    "To get the job's results, you can await completion and plot the output, as in the next code cell. This may take a few seconds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e2b2066-f8ae-4096-aa06-e8b9ffd52018",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Await job results.\n",
    "result = job.results()\n",
    "\n",
    "from matplotlib import pyplot\n",
    "\n",
    "# Quantinuum's emulators and quantum computers do not return probabilities, they return a dictionary of measurements.\n",
    "# (Note that since we targeted Syntax Checker, we expect to see that all measurements result in a zero.)\n",
    "# In order to visualize the result, we can use a histogram. Since the circuit contains only a single\n",
    "# measurement, we can expect that all values will be tied to the key \"m_0\".\n",
    "pyplot.hist(result['m_0'], bins=[0,1,2], width=0.5)\n",
    "pyplot.title(\"Result\")\n",
    "pyplot.xlabel(\"Measurement\")\n",
    "pyplot.ylabel(\"Repetitions\")\n",
    "\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7148b281-c95e-415b-8827-8af5e8ac0dcf",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "**See the histogram above? Congratulations, you've submitted a job with Azure Quantum! 👏**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a29cd66-1f35-4122-a8a2-be4dcb962287",
   "metadata": {},
   "source": [
    "### 5. Estimate costs\n",
    "\n",
    "To estimate the costs of running this program on a simulator or hardware, you can use the `service.estimate_cost` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f1a60e7-c95a-467a-ad48-d39710b48554",
   "metadata": {},
   "outputs": [],
   "source": [
    "cost = service.estimate_cost(circuit, repetitions=100, target=\"quantinuum.qpu.h1-1\")\n",
    "print(f\"Estimated cost: {cost.estimated_total} {cost.currency_code}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "121c3808-06c8-4775-afb6-2b5ab64a26f4",
   "metadata": {
    "nteract": {
     "transient": {
      "deleting": false
     }
    }
   },
   "source": [
    "### 6. Next steps\n",
    "Next, you can try running a program on Quantinuum's emulation and hardware targets. Just replace `quantinuum.sim.h1-1sc` with `quantinuum.sim.h1-1e` or `quantinuum.qpu.h1-1`. Or try another sample by navigating back to the sample gallery. The same \"hello world\" sample can be run with different quantum providers by choosing another option in the gallery card drop-down menu. Don't worry - your work here is automatically saved.\n",
    "\n",
    "To learn more about submitting Cirq circuits to Azure Quantum, review [this documentation](https://docs.microsoft.com/azure/quantum/quickstart-microsoft-cirq?pivots=platform-quantinuum).\n",
    "\n",
    "To learn more about job pricing, review the [Azure Quantum documentation on job costs](https://docs.microsoft.com/azure/quantum/azure-quantum-job-costs)."
   ]
  }
 ],
 "metadata": {
  "kernel_info": {
   "name": "python3"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  },
  "nteract": {
   "version": "nteract-front-end@1.0.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
